package com.yw.android.common.utils;

import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.PowerManager;
import android.provider.Settings;
import android.util.Base64;

import com.yw.android.common.base.BaseApp;
import com.yw.android.common.http.HTTPKeys;
import com.yw.android.sys.common.R;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * 系统接口
 *
 * @author yuanwei
 */
public class SystemUtils {
    private static String mProductType = "";
    /**
     * 是否支持设置搜索
     */
    private static Boolean sbSupportLauncherSearch;

    public static List<UsageStats> getUsageStats(Context act) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        long endt = calendar.getTimeInMillis();//结束时间
        calendar.add(Calendar.DAY_OF_MONTH, -1);//时间间隔为一个月
        long statt = calendar.getTimeInMillis();//开始时间
        UsageStatsManager usageStatsManager = (UsageStatsManager) act.getApplicationContext().getSystemService(Context.USAGE_STATS_SERVICE);
        if (usageStatsManager == null) {
            return new ArrayList<>();
        }
        List<UsageStats> queryUsageStats = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, statt, endt);
        if (queryUsageStats == null || queryUsageStats.isEmpty()) {
            return new ArrayList<>();
        }
        return queryUsageStats;
    }

    /**
     * 启动薄荷App
     *
     * @param context
     */
    public static void launchApp(Context context, String pkgName) {
        try {
            // 判断是否安装过App，否则去市场下载
            if (isAppInstalled(context, pkgName)) {
                Intent i = context.getPackageManager().getLaunchIntentForPackage(pkgName);
                if (i == null) {
                    goToMarket(context, pkgName);
                } else {
                    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(i);
                }
            } else {
                goToMarket(context, pkgName);
            }
        } catch (Throwable t) {
            ToastHelper.getInstance().shortToast(BaseApp.getAppContext(), R.string.start_other_app_error);
            LOG.e("[pkgName : " + pkgName + "] launchApp (Throwable)", t);
        }
    }

    /**
     * 检测某个应用是否安装
     *
     * @param context
     * @param packageName
     * @return
     */
    public static boolean isAppInstalled(Context context, String packageName) {
        try {
            context.getPackageManager().getPackageInfo(packageName, 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }

    /**
     * 去市场下载页面
     */
    public static void goToMarket(Context context, String packageName) {
        Uri uri = Uri.parse("market://details?id=" + packageName);
        Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
        try {
            context.startActivity(goToMarket);
        } catch (ActivityNotFoundException e) {
        }
    }

    /**
     * 获取手机又桌面图标的应用
     *
     * @param context
     * @return
     */
    public static List<ResolveInfo> getHasLaunchApps(Context context) {
        List<ResolveInfo> mApps = new ArrayList<>();
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);

        PackageManager pManager = context.getPackageManager();
        mApps = pManager.queryIntentActivities(intent, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
        return mApps;
    }

    /**
     * 获取当前网路类型
     *
     * @param context 上下文对象
     * @return 当前网路类型
     */
    public static String getNetworkType(Context context) {
        try {
            ConnectivityManager connMgr = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            if (null == connMgr) {
                LOG.e("get connectivity manager failed");
                return "";
            }

            NetworkInfo info = connMgr.getActiveNetworkInfo();

            if ((null == info) || (!info.isAvailable())) {
                return "";
            } else {
                int type = info.getType();
                String typeName = info.getTypeName();
                String subTypeName = info.getSubtypeName();
                String extInfo = ((type == ConnectivityManager.TYPE_WIFI)
                        ? getWifiExtraInfo(context) : getWirelessExtraInfo(info));

                if (TextUtils.empty(subTypeName)) {
                    return TextUtils.tidy(typeName + "/" + extInfo);
                } else {
                    return TextUtils.tidy(typeName + "(" + subTypeName + ")/" + extInfo);
                }
            }
        } catch (Throwable t) {
            LOG.e("get network type failed(Throwable): " + t.getMessage());
        }

        return "";
    }

    /**
     * 获取系统渠道号
     *
     * @return 系统ROM版本号
     */
    public static String getChannel() {
        String channel = getProperty("ro.vendor.channel.number", "");
        return ((null == channel) ? "" : channel);
    }

    /**
     * 获取系统SDK版本号
     *
     * @return 系统SDK版本号
     */
    public static String getOSSDKInt() {
        return ("" + Build.VERSION.SDK_INT);
    }

    /**
     * 获取Push客户端所在应用的版本号
     *
     * @return 应用版本号
     */
    public static String getVersion(Context context) {
        try {
            PackageManager pkgMgr = context.getPackageManager();
            PackageInfo info = pkgMgr.getPackageInfo(context.getPackageName(), 0);
            return info.versionCode + "";
        } catch (Throwable t) {
            LOG.e("get package info failed(Throwable): " + t.getMessage());
        }

        return "";
    }

    public static String getVersionName(Context context) {
        try {
            PackageManager pkgMgr = context.getPackageManager();
            PackageInfo info = pkgMgr.getPackageInfo(context.getPackageName(), 0);
            return info.versionName + "";
        } catch (Throwable t) {
            LOG.e("get package info failed(Throwable): " + t.getMessage());
        }

        return "";
    }

    /**
     * @return 应用的包名
     */
    public static String getPkgName(Context context) {
        try {
            PackageManager pkgMgr = context.getPackageManager();
            PackageInfo info = pkgMgr.getPackageInfo(context.getPackageName(), 0);
            return info.packageName;
        } catch (Throwable t) {
            LOG.e("get package name failed(Throwable): " + t.getMessage());
        }

        return "";
    }

    public static int getUid(Context context) {
        try {
            PackageManager pm = context.getPackageManager();
            ApplicationInfo ai = pm.getApplicationInfo("com.speedsoftware.rootexplorer", PackageManager.GET_ACTIVITIES);
            return ai.uid;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return -1;
    }

    /**
     * 获取Push客户端所在应用的版本号
     *
     * @return 应用的版本号
     */
    public static String getSoftwareVersion(Context context) {
        try {
            PackageManager pkgMgr = context.getPackageManager();
            PackageInfo info = pkgMgr.getPackageInfo(context.getPackageName(), 0);
            return info.versionName;
        } catch (Throwable t) {
            LOG.e("get version name failed(Throwable): " + t.getMessage());
        }

        return "";
    }

    /**
     * 获取客户端标志，包名+版本号
     *
     * @param context 上下文
     * @return 应用的版本号
     */
    public static String getClientName(Context context) {
        try {
            String pkgName = context.getPackageName();
            PackageInfo info = context.getPackageManager().getPackageInfo(pkgName, 0);
            return (pkgName + "/" + info.versionName);
        } catch (Throwable t) {
            LOG.e("get user agent failed(Throwable): " + t.getMessage());
        }

        return "";
    }

    /**
     * 判断网络连接是否可用
     *
     * @param context 上下文环境
     * @return true 可用；false 不可用
     */
    public static boolean isNetworkAvailable(Context context) {
        try {
            ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(
                    Context.CONNECTIVITY_SERVICE);
            NetworkInfo info = connMgr.getActiveNetworkInfo();
            return ((null != info) && info.isAvailable());
        } catch (Throwable t) {
            LOG.e("get active network info failed(Throwable): " + t.getMessage());
        }

        return false;
    }

    /**
     * 读取网络描述信息
     *
     * @param context 上下文环境
     * @return 网络描述信息
     */
    public static String getNetworkDescriptor(Context context) {
        try {
            ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(
                    Context.CONNECTIVITY_SERVICE);
            NetworkInfo info = connMgr.getActiveNetworkInfo();

            if (null != info) {
                return ("type=" + info.getType() + "/" + info.getTypeName()
                        + "; subtype=" + info.getSubtype() + "/" + info.getSubtypeName()
                        + "; ext=" + info.getExtraInfo() + "; conn=" + info.isConnected()
                        + "; available=" + info.isAvailable());
            } else {
                return "unknown";
            }
        } catch (Throwable t) {
            return t.getMessage();
        }
    }

    /**
     * 读取当前屏幕状态，默认为亮屏状态
     *
     * @param context 上下文
     * @return true 亮屏状态；false 黑屏状态
     */
    @SuppressWarnings("deprecation")
    public static boolean isScreenOn(Context context) {
        try {
            PowerManager pm = (PowerManager) context.getSystemService(
                    Context.POWER_SERVICE);

            if (Build.VERSION.SDK_INT >= 20) {
                return pm.isInteractive();
            } else {
                return pm.isScreenOn();
            }
        } catch (Throwable t) {
            LOG.e("get screen status failed(Throwable): " + t.getMessage());
        }

        return true;
    }

    /**
     * 是否是用户使用模式
     *
     * @param context 应用上下文
     * @return true 是；false 否
     */
    public static boolean isUserMode(Context context) {
        try {
            int closed = Settings.Secure.getInt(context.getContentResolver(), "at_closed", 0);
            int used = Settings.Secure.getInt(context.getContentResolver(), "at_flag_u", 0);
            return ((1 == closed) && (1 == used));
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获取移动定制机模式，合作型（1）/深度合作型（2）/战略型（3）
     *
     * @return 移动定制机模式
     */
    public static String getCMCCMode() {
        String mode = getProperty("persist.qiku.cmcc.mode", "0");
        return ((null == mode) ? "0" : mode);
    }

    /**
     * 判断当前手机是否是海外版本
     * 读取系统海外版本标志，如果为空或者0，则为国内版本
     *
     * @return true 海外版本；false 国内版本
     */
    public static boolean isAbroad() {
        String mode = getProperty("persist.qiku.operators.isabroad", "0");
        return (!(TextUtils.equals(mode, "0") || TextUtils.empty(mode)));
    }

    /**
     * make true current connect service is wifi
     *
     * @param mContext
     * @return
     */
    public static boolean isWifi(Context mContext) {
        ConnectivityManager connectivityManager = (ConnectivityManager) mContext
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
        if (activeNetInfo != null
                && activeNetInfo.getType() == ConnectivityManager.TYPE_WIFI) {
            return true;
        }
        return false;
    }

    /**
     * 获取当前网路详情，在数据网络模式下
     *
     * @param info 网络
     * @return 当前网路类型
     */
    private static String getWirelessExtraInfo(NetworkInfo info) {
        return info.getExtraInfo();
    }

    /**
     * 获取当前网路类型，在WIFI网络模式下
     *
     * @param context 上下文对象
     * @return 当前网路类型
     */
    private static String getWifiExtraInfo(Context context) {
        try {
            WifiManager wifiMgr = (WifiManager) context.getSystemService(
                    Context.WIFI_SERVICE);

            if (null == wifiMgr) {
                LOG.e("get WIFI manager failed");
            } else {
                if (WifiManager.WIFI_STATE_ENABLED == wifiMgr.getWifiState()) {
                    WifiInfo info = wifiMgr.getConnectionInfo();

                    if (null != info) {
                        return (replace(info.getBSSID(), ":", "")
                                + "@" + getB64String(info.getSSID()));
                    }
                }
            }
        } catch (Throwable t) {
            LOG.e("get WIFI info failed(Throwable): " + t.getMessage());
        }

        return "";
    }

    /**
     * 用户是否允许执行，在入网或者现网模式下用户禁止执行
     * 如果是入网或者现网模式的系统，需要检查用户是否允许执行
     * 如果是正常用户量产系统，不需要查询用户允许情况
     *
     * @param context 应用上下文对象
     * @return true 允许执行；false 不允许执行
     */
    public static boolean isRunAllowed(Context context) {
        if (isRunInAskMode() && (!isApplicationAuthenticated(context))) {
            LOG.i("phone is ask mode and non-auth ...");
            return false;
        }
        return true;
    }

    /**
     * 是否是入网或者现网测试模式
     *
     * @return true 是；false 不是
     */
    private static boolean isRunInAskMode() {
        String m1 = getProperty("persist.qiku.defaultmode", "0");
        return TextUtils.equals(m1, "1");
    }

    /**
     * 检查应用是否对当前应用授权运行
     *
     * @param context 应用上下文对象
     * @return true 授权；false 没有授权
     */
    private static boolean isApplicationAuthenticated(Context context) {
        if (isCoreService(context)) {
            return isCoreServiceAuthenticated(context);
        } else {
            return isCloudServiceAuthenticated(context);
        }
    }

    /**
     * 查询当前是否处于核心服务中
     *
     * @return true 运行于核心服务中；false 未运行于核心服务中
     */
    private static boolean isCoreService(Context context) {
        try {
            String packageName = context.getPackageName();
            return TextUtils.equalsIgnoreCase(packageName, "com.cloudsx.android.coreservice");
        } catch (Throwable t) {
            LOG.e("get package name failed(Throwable): " + t.getMessage());
        }

        return false;
    }

    /**
     * 检查用户是否对当前应用（核心应用）授权运行
     *
     * @param context 应用上下文对象
     * @return true 授权；false 没有授权
     */
    private static boolean isCoreServiceAuthenticated(Context context) {
        try {
            SharedPreferences sf = context.getSharedPreferences("security_pref", Context.MODE_PRIVATE);
            return sf.getBoolean("ALL_ALLOW_FLAG", false);
        } catch (Throwable t) {
            LOG.e("get Boolean(ALL_ALLOW_FLAG) failed(Throwable): " + t.getMessage());
        }

        return true;
    }

    /**
     * 检查用户是否对当前应用（云服务）授权运行
     *
     * @param context 应用上下文对象
     * @return true 授权；false 没有授权
     */
    private static boolean isCloudServiceAuthenticated(Context context) {
        try {
            Class<?> clazz = Class.forName("com.cloudsync.android.dao.UserConfigurePreferences");
            Constructor<?> c = clazz.getConstructor(Context.class, String.class);
            Object o = c.newInstance(context, "userconfig");
            Method getString = clazz.getMethod("getString", String.class, String.class);
            String value = (String) getString.invoke(o, "ALL_ALLOW_FLAG", "FALSE");
            return TextUtils.equalsIgnoreCase(value, "TRUE");
        } catch (ClassNotFoundException e) {
            LOG.w("invoke getString(ALL_ALLOW_FLAG) failed(ClassNotFoundException): " + e.getMessage());
        } catch (NoClassDefFoundError e) {
            LOG.w("invoke getString(ALL_ALLOW_FLAG) failed(NoClassDefFoundError): " + e.getMessage());
        } catch (Throwable t) {
            LOG.w("invoke getString(ALL_ALLOW_FLAG) failed(Throwable): " + t.getMessage());
        }

        return true;
    }

    /**
     * 对指定字符串，使用Base64编码
     *
     * @param node 指定字符串
     * @return 编码后字符串
     */
    private static String getB64String(String node) {
        try {
            if (!empty(node)) {
                return new String(Base64.encode(node.getBytes("UTF-8"),
                        Base64.NO_WRAP), "UTF-8");
            }
        } catch (Exception e) {
            LOG.w("[" + node
                    + "] base64 encode failed(" + e.getClass().getSimpleName()
                    + "): " + e.getMessage());
        }

        return "";
    }

    /**
     * 将字符串中所有指定子字符串替换成指定字符串
     *
     * @param s       字符串
     * @param regular 指定子字符串
     * @param replace 指定字符串
     * @return 替换后的字符串
     */
    private static String replace(String s, String regular, String replace) {
        if (!TextUtils.empty(s)) {
            return s.replaceAll(regular, replace);
        } else {
            return s;
        }
    }

    /**
     * 获取系统属性
     *
     * @param key          对应关键字
     * @param defaultValue 默认值
     * @return 系统属性值
     */
    public static String getProperty(String key, String defaultValue) {
        try {
            Class<?> clazz = Class.forName("android.os.SystemProperties");
            Method method = clazz.getDeclaredMethod("get", String.class);
            method.setAccessible(true);
            return (String) method.invoke(null, key);
        } catch (NoSuchMethodException e) {
            LOG.i("invoke get " + key + " failed(NoSuchMethodException): " + e.getMessage());
        } catch (IllegalAccessException e) {
            LOG.i("invoke get " + key + " failed(IllegalAccessException): " + e.getMessage());
        } catch (IllegalArgumentException e) {
            LOG.i("invoke get " + key + " failed(IllegalArgumentException): " + e.getMessage());
        } catch (InvocationTargetException e) {
            LOG.i("invoke get " + key + " failed(InvocationTargetException): " + e.getMessage());
        } catch (ClassNotFoundException e) {
            LOG.i("invoke get " + key + " failed(ClassNotFoundException): " + e.getMessage());
        } catch (Throwable t) {
            LOG.i("invoke get " + key + " failed(Throwable): " + t.getMessage());
        }

        return defaultValue;
    }

    /**
     * 判断字符串是否为空
     *
     * @param s 字符串
     * @return true 空；false 非空
     */
    private static boolean empty(String s) {
        return ((null == s) || (s.length() <= 0));
    }

    /**
     * 获取系统当前使用的语言
     *
     * @return
     */
    public static String getCurLang() {
        return Locale.getDefault().getLanguage();
    }

    public static String getLanguage() {
        Locale mLocale = Locale.getDefault();
        if (mLocale != null) {
            String language = mLocale.getLanguage();
            String country = mLocale.getCountry();
            return language + "-" + country;
        }
        return "";
    }

    /**
     * 获取手机非系统应用
     */
    public static Map<String, PackageInfo> getLauncherApp(Context mContext) {
        Map<String, PackageInfo> result = new HashMap<>();
        List<PackageInfo> packages = mContext.getPackageManager().getInstalledPackages(0);
        for (PackageInfo mPackageInfo : packages) {
            if ((!TextUtils.equals(mContext.getPackageName(), mPackageInfo.packageName))
                    && (!TextUtils.containsIgnoreCase(mPackageInfo.packageName, ".launcher"))
                    && BaseApp.getAppContext().getPackageManager().getLaunchIntentForPackage(mPackageInfo.packageName) != null) {
                result.put(mPackageInfo.packageName, mPackageInfo);
            }
        }
        return result;
    }

    public static Map<String, PackageInfo> getLaunchApp4Name(Context mContext) {
        Map<String, PackageInfo> result = new HashMap<>();
        List<PackageInfo> packages = mContext.getPackageManager().getInstalledPackages(0);
        for (PackageInfo mPackageInfo : packages) {
            if ((!TextUtils.equals(mContext.getPackageName(), mPackageInfo.packageName))
                    && (!TextUtils.containsIgnoreCase(mPackageInfo.packageName, ".launcher"))
                    && BaseApp.getAppContext().getPackageManager().getLaunchIntentForPackage(mPackageInfo.packageName) != null) {
                result.put(getApplicationName(mPackageInfo.packageName), mPackageInfo);
            }
        }
        return result;
    }

    /**
     * 获取所有应用
     */
    public static HashMap<String, PackageInfo> getAllApp(Context mContext) {
        HashMap<String, PackageInfo> result = new HashMap<>();
        List<PackageInfo> packages = mContext.getPackageManager().getInstalledPackages(0);
        for (PackageInfo mPackageInfo : packages) {
            result.put(mPackageInfo.packageName, mPackageInfo);
        }
        return result;
    }

    /**
     * 获取所有应用
     */
    public static HashMap<String, PackageInfo> getAllAppName(Context mContext) {
        HashMap<String, PackageInfo> result = new HashMap<>();
        List<PackageInfo> packages = mContext.getPackageManager().getInstalledPackages(0);
        for (PackageInfo mPackageInfo : packages) {
            result.put(getApplicationName(mPackageInfo.packageName), mPackageInfo);
        }
        return result;
    }

    public static String getApplicationName(String pkgName) {
        PackageManager packageManager = null;
        ApplicationInfo applicationInfo = null;
        try {
            packageManager = BaseApp.getAppContext().getPackageManager();
            applicationInfo = packageManager.getApplicationInfo(pkgName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            applicationInfo = null;
        }
        return (String) packageManager.getApplicationLabel(applicationInfo);
    }

    public static String getsPercentFlag(Context context) {
        try {
            if (getVersion(context, "com.qiku.logsystem") >= 130) {
                return String.valueOf(Settings.Secure.getInt(context.getContentResolver(), HTTPKeys.SETTINGS_FLAG_CLOSED, 0));
            } else {
                return String.valueOf(Settings.Secure.getInt(context.getContentResolver(), HTTPKeys.SETTINGS_FLAG_CLOSED, 1));
            }
        } catch (Throwable e) {
            LOG.e("getsPercentFlag ", e);
            return "1";
        }
    }

    public static int getVersion(Context context, String pkgName) {
        try {
            PackageManager manager = context.getPackageManager();
            PackageInfo info = manager.getPackageInfo(pkgName, 0);
            return info.versionCode;

        } catch (Exception e) {
            LOG.e("[pkgName : " + pkgName + "] getVersion ", e);
        }
        return -1;
    }

    public static String getnPercentFlag(Context context) {
        try {
            if (getVersion(context, "com.qiku.logsystem") >= 130) {
                return String.valueOf(Settings.Secure.getInt(context.getContentResolver(), HTTPKeys.SETTINGS_FLAG_USED, 0));
            } else {
                return String.valueOf(Settings.Secure.getInt(context.getContentResolver(), HTTPKeys.SETTINGS_FLAG_USED, 1));
            }
        } catch (Throwable e) {
            LOG.e("getnPercentFlag ", e);
            return "1";
        }
    }

    public static boolean isSupportLauncherSearch(Context context) {
        if (sbSupportLauncherSearch == null) {
            try {
                Context packageContext = context.createPackageContext("com.android.settings", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
                if (packageContext != null) {
                    Class<?> cls = packageContext.getClassLoader().loadClass("com.android.settings.SettingsActivity");
                    if (cls != null) {
                        Field field = cls.getDeclaredField("QK_SUPPORT_LAUNCHER_SEARCH");
                        field.setAccessible(true);
                        if (field != null) {
                            sbSupportLauncherSearch = field.getBoolean(null);
                        }
                    }
                }
            } catch (Exception e) {
                LOG.e("isSupportLauncherSearch exception = " + e.toString());
            }

            if (sbSupportLauncherSearch == null) {
                sbSupportLauncherSearch = false;
            }
            LOG.d("isSupportLauncherSearch = " + sbSupportLauncherSearch);
        }
        return sbSupportLauncherSearch;
    }
}
